package com.wenjie.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.Row;
import com.wenjie.common.utils.StringUtils;
import com.wenjie.service.ICodeTemplateHandle;
import com.wenjie.vo.gen.TableInfo;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.stereotype.Component;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author wenjie
 * @Description 对代码模版进行处理
 * @date 2024/7/23 17:16
 */
@Component
public class CodeTemplateHandle implements ICodeTemplateHandle {

    @Override
    public String exeDetail(String tableName, String templateValue, String cusParam) {

        // 获取一下表的字段信息
        TableInfo TableInfo = this.getTableInfo(tableName);

        VelocityContext context = new VelocityContext();
        context.put("tableInfo", JSONUtil.parseObj(TableInfo));
        context.put("custom", JSONUtil.parseObj(cusParam));
        context.put("tools", new CodeTemplateTools());

        // 处理器处理
        return handle(context, templateValue);
    }

    /**
     * @Description 对代码模版进行解析
     * @author wenjie
     * @date 2024/7/23 17:30
     */
    private String handle(VelocityContext context, String templateValue) {
        // 初始化Velocity引擎
        Velocity.init();

        // 使用evaluate方法加载并执行VM模板
        StringWriter writer = new StringWriter();
        Velocity.evaluate(context, writer, "", templateValue);
        return writer.toString();
    }


    /**
     * @Description 处理模版中的变量
     * @author wenjie
     * @date 2024/7/29 17:22
     */
    private String handle_variable(JSONObject tableJson, String templateValue) {

        // 获取变量
//        String regex = "(\\$[a-zA-Z][a-zA-Z0-9\\.]*)";
        String regex = "(\\$[a-zA-Z\\._]+)\\s*(.)?";

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(templateValue);

        while (matcher.find()) {
            String group = matcher.group(1);
            String isTools = matcher.group(2);
            if ("(".equals(isTools) || isTools == null) continue;

            String substring = group.substring(1);

            Object byPath = tableJson.getByPath(substring);

            if (byPath == null) {
                continue;
//                throw new RuntimeException("没有找到匹配的配置" + group);
            }
            templateValue = templateValue.replace(group, byPath.toString());
        }
        return templateValue;
    }

    /**
     * @Description 处理一下if
     * @author wenjie
     * @date 2024/7/29 15:48
     */
    private String handle_if(JSONObject tableJson, String templateValue) {

        // 获取变量
        String regex = "#if\\((.*)\\)([\\s\\S]*?)#end";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(templateValue);


        while (matcher.find()) {
            String group = matcher.group(1);
            Boolean flg = false;
            if (group.indexOf("||") > 0) {
                String[] split = matcher.group(1).split("\\|\\|");
                flg = huo(split);
            } else {
                if (group.indexOf("&&") > 0) {
                    String[] split = matcher.group(1).split("&&");
                    flg = yu(split);
                } else {
                    String[] strs = new String[]{matcher.group(1)};
                    flg = huo(strs);
                }

            }


            if (flg) {
                templateValue = templateValue.replace(matcher.group(), matcher.group(2));
            } else {
                templateValue = templateValue.replace(matcher.group(), "");
            }
        }

        return templateValue;
    }

    private Boolean yu(String[] split1) {
        Boolean flg = true;
        for (String item : split1) {
            if (item.indexOf("==") > 0) {
                String[] split = item.split("==");
                if (!(split[0].trim().equals(split[1].trim()))) {
                    flg = false;
                    break;
                }
            } else {
                if (item.indexOf("!=") > 0) {
                    String[] split = item.split("!=");
                    if (split[0].trim().equals(split[1].trim())) {
                        flg = false;
                        break;
                    }
                } else {
                    if (StringUtils.isBlank(item) || item.trim().equals("false")) {
                        flg = false;
                        break;
                    }
                }
            }
        }

        return flg;
    }

    private Boolean huo(String[] split1) {
        Boolean flg = false;
        for (String item : split1) {
            if (item.indexOf("==") > 0) {
                String[] split = item.split("==");
                if (split[0].trim().equals(split[1].trim())) {
                    flg = true;
                    break;
                }
            } else {
                if (item.indexOf("!=") > 0) {
                    String[] split = item.split("!=");
                    if (!split[0].trim().equals(split[1].trim())) {
                        flg = true;
                        break;
                    }
                } else {
                    if (!(StringUtils.isBlank(item) || item.trim().equals("false"))) {
                        flg = true;
                        break;
                    }
                }
            }
        }
        return flg;
    }


    /**
     * @Description 处理一下for
     * @author wenjie
     * @date 2024/8/6 10:46
     */
    private String handle_for(JSONObject tableJson, String templateValue) {
        return replace_for(tableJson, templateValue);
    }

    /**
     * @Description 解析for格式的语句
     * @author wenjie
     * @date 2024/8/6 10:46
     */
    private String replace_for(JSONObject jsonObject, String templateValue) {
        // 获取变量
        String regex = "#foreach\\(\\s*(\\$[0-9a-zA-z_]+)\\s+in\\s+([^\\)]+)\\s*\\)\\n";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(templateValue);
        if (matcher.find()) {
            int i = countEnd(1, templateValue, matcher.end());
            String content = templateValue.substring(matcher.end(), i - 4);

            // 处理里面的内容
            String itemKey = matcher.group(1);
            String valueKey = matcher.group(2);

            JSONArray array = null;
            try {
                array = JSONUtil.parseArray(valueKey);
            } catch (Exception e) {
                valueKey = valueKey.substring(1);
                Object byPath = jsonObject.getByPath(valueKey);
                array = JSONUtil.parseArray(byPath);
            }

            StringBuffer newContent = new StringBuffer();

            for (Object item : array) {
                String regex1 = "\\$" + itemKey.substring(1) + "\\.([a-zA-Z\\.]*)";
                // 处理一下数据
                Pattern pattern1 = Pattern.compile(regex1);
                Matcher matcher1 = pattern1.matcher(content);
                String replace = content;

                if (matcher1.find()) {
                    do {
                        String group = matcher1.group();
                        String group1 = matcher1.group(1);
                        JSONObject jsonObject1 = JSONUtil.parseObj(item);
                        Object byPath = jsonObject1.getByPath(group1);
                        replace = replace.replace(group, String.valueOf(byPath));
                    } while (matcher1.find());
                } else {
                    replace = replace.replace(itemKey, String.valueOf(String.valueOf(item)));
                }
                newContent.append(replace);
            }

            String string = newContent.toString();
            templateValue = StringUtils.sub(templateValue, matcher.start(), i, string);
            return replace_for(jsonObject, templateValue);
        } else {
            return templateValue;
        }


    }


    private int countEnd(int flg, String value, int start) {
        int end_index = value.indexOf("#end", start);

        if (end_index > 0) flg--;
        end_index += 4;
        String substring = value.substring(start, end_index);
        int i = StringUtils.countOccurrences(substring, "#foreach(");
        int j = StringUtils.countOccurrences(substring, "#if(");
        flg = flg + i + j;
        if (flg == 0) return end_index;
        else {
            return this.countEnd(flg, value, end_index);
        }
    }


    /**
     * @Description 根据表的名称, 生成表信息
     * @author wenjie
     * @date 2024/7/23 17:33
     */
    public TableInfo getTableInfo(String tableName) {
        TableInfo TableInfo = new TableInfo();
        TableInfo.setColumns(new ArrayList<>());

        // 获取表的备注信息
        Object o = Db.selectObject("SELECT TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '" + tableName + "'and TABLE_SCHEMA = 'factory_statistics1'" + ";");
        TableInfo.setName(tableName);
        TableInfo.setComment(String.valueOf(o));

        // 获取表的字段信息
        List<Row> rows = Db.selectListBySql("SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + tableName + "'and TABLE_SCHEMA = 'factory_statistics1'" + ";");

        for (Row row : rows) {
            TableInfo.Column column = new TableInfo.Column();
            column.setName(row.getString("COLUMN_NAME"));

            column.setType(row.getString("DATA_TYPE"));

            column.setCanNull(!"No".equals(row.getString("IS_NULLABLE")));

            column.setIsPrimary("PRI".equals(row.getString("COLUMN_KEY")));

            column.setComment(row.getString("COLUMN_COMMENT"));
            TableInfo.getColumns().add(column);
        }

        return TableInfo;
    }

}
